package net.zoneland.zrdp.system.service.impl;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

import net.zoneland.zrdp.common.utils.DateUtil;
import net.zoneland.zrdp.common.utils.spring.SpringUtils;
import net.zoneland.zrdp.system.domain.SysNoticeComment;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import net.zoneland.zrdp.common.exception.ServiceException;
import net.zoneland.zrdp.system.domain.SysNotice;
import net.zoneland.zrdp.system.mapper.SysNoticeMapper;
import net.zoneland.zrdp.system.service.ISysNoticeService;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


/**
 * 公告 服务层实现
 *
 * @author zonevue
 */
@Service
public class SysNoticeServiceImpl implements ISysNoticeService {
    private static final Logger LOGGER = LoggerFactory.getLogger(SysNoticeServiceImpl.class);

    @Resource
    private SysNoticeMapper noticeMapper;

    /**
     * 查询公告信息
     *
     * @param noticeId 公告ID
     * @return 公告信息
     */
    @Override
    public SysNotice selectNoticeById(final Long noticeId) {
        return noticeMapper.selectNoticeById(noticeId);
    }

    /**
     * 查询通知公告new
     *
     * @param noticeId 通知公告new主键
     * @return 通知公告new
     */
    @Override
    public SysNotice selectNoticeByNoticeId(final Long noticeId) {
        return noticeMapper.selectNoticeByNoticeId(noticeId);
    }
    /**
     * 查询公告列表
     *
     * @param notice 公告信息
     * @return 公告集合
     */
    @Override
    public List<SysNotice> selectNoticeList(final SysNotice notice) {
        return noticeMapper.selectNoticeList(notice);
    }

    /**
     * 导出公告列表
     *
     * @param notice 公告信息
     * @return 公告集合
     */
    @Override
    public List<SysNotice> selectExportNoticeList(final SysNotice notice) {
        return noticeMapper.selectExportNoticeList(notice);
    }

    /**
     * 新增通知公告new
     *
     * @param sysNotice 通知公告new
     * @return 结果
     */
    @Transactional
    @Override
    public int insertNotice(final SysNotice sysNotice) {
        sysNotice.setCreateTime(DateUtil.getNowLocalDateTime());
        final int rows = noticeMapper.insertNotice(sysNotice);
        insertSysNoticeComment(sysNotice);
        return rows;
    }

    /**
     * 修改通知公告new
     *
     * @param sysNotice 通知公告new
     * @return 结果
     */
    @Transactional
    @Override
    public int updateNotice(final SysNotice sysNotice) {
        sysNotice.setUpdateTime(DateUtil.getNowLocalDateTime());
        noticeMapper.deleteNoticeCommentByNoticeId(sysNotice.getNoticeId());
        insertSysNoticeComment(sysNotice);
        return noticeMapper.updateNotice(sysNotice);
    }

    /**
     * 批量删除通知公告new
     *
     * @param noticeIds 需要删除的通知公告new主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteNoticeByIds(final Long[] noticeIds) {
        noticeMapper.deleteNoticeCommentByNoticeIds(noticeIds);
        return noticeMapper.deleteNoticeByIds(noticeIds);
    }

    /**
     * 删除通知公告new信息
     *
     * @param noticeId 通知公告new主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteNoticeById(final Long noticeId) {
        noticeMapper.deleteNoticeCommentByNoticeId(noticeId);
        return noticeMapper.deleteNoticeById(noticeId);
    }

    /**
     * 新增公告评论信息
     *
     * @param sysNotice 通知公告new对象
     */
    public void insertSysNoticeComment(final SysNotice sysNotice) {
        final Long noticeId = sysNotice.getNoticeId();
        final List<SysNoticeComment> sysNoticeCommentList = sysNotice.getSysNoticeCommentList();
        Optional.ofNullable(sysNoticeCommentList)
            .filter(CollectionUtils::isNotEmpty)
            .ifPresent(list -> noticeMapper.batchNoticeComment(list, noticeId));
    }
    /**
     * 导入公告数据。
     * 因为业务需要单条进行导入或者更新，并且记录单条的执行结果，不能因为其中一条失败就导致全部失败（收集出错的条目），因此不开启事务。因此抑制 sonar(java:S2229)
     *
     * @param noticeList 公告数据列表
     * @param isUpdateSupport 是否更新已经存在的数据
     * @param operName 操作用户
     * @return 结果
     */

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    @SuppressWarnings("java:S2229")
    public String importNotice(final List<SysNotice> noticeList, final boolean isUpdateSupport, final String operName) {
        if (CollectionUtils.isEmpty(noticeList)) {
            throw new ServiceException("导入数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        final StringBuilder successMsg = new StringBuilder();
        final StringBuilder failureMsg = new StringBuilder();
        for (final SysNotice notice : noticeList) {
            try {
                // 验证是否存在这个数据
                final SysNotice tempNotice = noticeMapper.selectNoticeByTitle(notice.getNoticeTitle());
                if (Objects.isNull(tempNotice)) {
                    notice.setCreateBy(operName);
                    SpringUtils.getBean(ISysNoticeService.class).insertNotice(notice);
                    successNum++;
                    successMsg.append("<br/>").append(successNum).append("、标题 ").append(notice.getNoticeTitle()).append(" 导入成功");
                } else if (isUpdateSupport) {
                    notice.setNoticeId(tempNotice.getNoticeId());
                    notice.setUpdateBy(operName);
                    SpringUtils.getBean(ISysNoticeService.class).updateNotice(notice);
                    successNum++;
                    successMsg.append("<br/>").append(successNum).append("、标题 ").append(notice.getNoticeTitle()).append(" 更新成功");
                } else {
                    failureNum++;
                    failureMsg.append("<br/>").append(failureNum).append("、标题 ").append(notice.getNoticeTitle()).append(" 已存在");
                }
            } catch (final Exception e) {
                failureNum++;
                final String msg = "<br/>" + failureNum + "、标题 " + notice.getNoticeTitle() + " 导入失败：";
                failureMsg.append(msg).append(e.getMessage());
                LOGGER.error(msg, e);
            }
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }
}
